
import { isObject, _has, _type } from '../utils/index.js'
import { _mirror } from '../math/mirror.js'
import { _rotate2, _o, isMatrix, _dis, _mid } from "../math/index.js"
import { _colors } from '../color/index.js'

export const _show = (obj) => {
    if (isObject(obj)) {
        if (_has(obj, 'show')) {
            return obj.show
        } else if (_has(obj, 'type')) {
            return obj.type !== 'none'
        } else if (_has(obj, 'pattern')) {
            return obj.pattern !== 'none'
        } else {
            return true
        }
        // return obj && (!_has(obj, 'show') || obj.show) 
    } else if (_type(obj) === 'string') {
        return obj !== 'none'
    }
    return obj
}




// 判断曲线
export const isCurve = (curve) => {
    return curve && curve !== 'none'
}

// 外圈顶点
export const _borderPoints = (matrix, mirror) => {
    let index = isObject(mirror) ? mirror.borderIndex : 0
    let len = matrix.length
    return matrix[(index >= len || index <= 0) ? (len - 1) : index]
}
// 镜像点
const _mirrorPoint = (point, index, mirrorPoints) => {
    return mirrorPoints ? mirrorPoints[index % mirrorPoints.length] : point
}

export const _mirrorColor = (mirror) => {
    let colorObj = null
    if (mirror && mirror.color) {
        let { color, alpha, fill, fillRule } = mirror
        colorObj = {
            type: color,
            color, alpha, fill, fillRule
        }
    }
    return colorObj
}

export const _colorProps = (color, n, alpha = 1) => {
    if (!_show(color)) {
        return () => {
            return {}
        }
    }
    // 兼容对象
    let type, fill = false, fillRule
    if (isObject(color)) {
        type = color.type
        alpha = color.alpha
        fill = _type(color.fill) === 'string' ? color.fill !== 'none' : color.fill
        fillRule = color.fillRule
    } else {
        type = color
    }
    let colors = _colors(type, n, alpha)
    return (index) => {
        let color = colors[index % n]
        let stroke = color
        let props = { stroke }
        if (fill) {
            props.fill = color
            if (fillRule) {
                props.fillRule = fillRule
            }
        }

        return props
    }
}

// 合并属性 ，
// 第一个为 none，后续不能覆盖
export const _mergeProps = (a, b) => {
    let props = {}
    Object.keys(a).forEach(t => {
        if (_has(a, t)) {
            if (a[t] !== 'none') {
                props[t] = b[t] || a[t]
            }
        } else if (_has(b, t)) {
            if (b[t] !== 'none') {
                props[t] = b[t]
            }
        }
    })
    return props
}

export const _merge = (a, b) => {
    return { ...a, ...b }
}

// 镜像  被 algorithm/mirror代替
export const _mirrorPath = (pathFn, options, props) => {
    let { points, mirror, mirrorPoints, alpha = 1 } = options
    let color = mirror.color || options.color
    let n = points.length
    let _props = _colorProps(color, n, alpha)
    let fn = (ps, index) => {
        let o = _o(ps)
        let r = _dis(o, ps[0])
        return pathFn({
            ...options,
            points: ps,
            o,
            r,
            mirror: null
        }, _mergeProps(props, _props(index)))
    }

    if (isMatrix(points)) {

        let mirrorPoints = _borderPoints(points, mirror)
        return points.map((t, i) => {
            return _mirrorPath(pathFn, {
                ...options,
                points: t,
                mirrorPoints
            },
                _merge(props, _props(i))
            )
        })
    }

    let type, radio
    if (isObject(mirror)) {
        type = mirror.type
        radio = mirror.radio || 1
    } else {
        type = mirror
        radio = 1
    }

    switch (type) {
        case 'none':
            return []
        case 'vertex': {
            return points.map((t, i) => {
                let mp = _mirrorPoint(t, i, mirrorPoints)
                let ps = _mirror(points, mp, radio)
                return fn(ps, i)
            })
        }
        case 'edge': {
            let ms = _mid(points)
            let mms = mirrorPoints ? _mid(mirrorPoints) : null
            return ms.map((t, i) => {
                let mp = _mirrorPoint(t, i, mms)
                let ps = _mirror(points, mp, radio)
                return fn(ps, i)
            })
        }

        case 'edgeMid': {
            let ms = _mid(points)
            let mms = mirrorPoints ? _mid(mirrorPoints) : null
            return ms.map((t, i) => {
                let mp = _mirrorPoint(t, i, mms)
                let ps = _mirror(ms, mp, radio)
                return fn(ps, i)
            })
        }
        case 'radiusMid': {
            let o = _o(points)
            return points.map((t, i) => {
                let mp = _mirrorPoint(t, i, mirrorPoints)
                let rm = _mid(mp, o)
                let ps = _mirror(points, rm, radio)
                return fn(ps, i)
            })

        }

    }
}



